bitkeeper revision 1.22.2.20 (3e4bb0deGlYf76D1jtppEmaeeRJyVQ)
authoriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>
Thu, 13 Feb 2003 14:51:10 +0000 (14:51 +0000)
committeriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>
Thu, 13 Feb 2003 14:51:10 +0000 (14:51 +0000)
Pulled in IO APIC stuff from linux-2.4.21-pre4

12 files changed:
xen-2.4.16/arch/i386/io_apic.c
xen-2.4.16/arch/i386/mpparse.c
xen-2.4.16/drivers/net/Makefile
xen-2.4.16/drivers/net/e1000/e1000.h
xen-2.4.16/drivers/net/e1000/e1000_hw.c
xen-2.4.16/drivers/net/e1000/e1000_main.c
xen-2.4.16/drivers/net/e1000/e1000_osdep.h
xen-2.4.16/include/asm-i386/apic.h
xen-2.4.16/include/asm-i386/apicdef.h
xen-2.4.16/include/asm-i386/io_apic.h
xen-2.4.16/include/asm-i386/mpspec.h
xen-2.4.16/include/asm-i386/smpboot.h

index c5ae3a3107895eca5d7b09b63a2478a414ff2b5e..8ba37e3903ade34cec135243640afa03114a783f 100644 (file)
 #include <xeno/config.h>
 #include <asm/mc146818rtc.h>
 #include <asm/io.h>
-#include <asm/desc.h>
 #include <asm/smp.h>
+#include <asm/desc.h>
+#include <asm/smpboot.h>
+
+
+static unsigned int nmi_watchdog;  /* XXXX XEN */
+
+#undef APIC_LOCKUP_DEBUG
+
+#define APIC_LOCKUP_DEBUG
 
 static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED;
 
+unsigned int int_dest_addr_mode = APIC_DEST_LOGICAL;
+unsigned char int_delivery_mode = dest_LowestPrio;
+
+
 /*
  * # of IRQ routing registers
  */
@@ -47,6 +59,7 @@ int nr_ioapic_registers[MAX_IO_APICS];
 
 /*
  * This is performance-critical, we want to do it O(1)
+ *
  * the indexing order of this array favors 1:1 mappings
  * between pins and IRQs.
  */
@@ -60,7 +73,7 @@ static struct irq_pin_list {
  * shared ISA-space IRQs, so we have to support them. We are super
  * fast in the common case, and fast for shared ISA-space IRQs.
  */
-static void add_pin_to_irq(unsigned int irq, int apic, int pin)
+static void __init add_pin_to_irq(unsigned int irq, int apic, int pin)
 {
        static int first_free_entry = NR_IRQS;
        struct irq_pin_list *entry = irq_2_pin + irq;
@@ -78,6 +91,26 @@ static void add_pin_to_irq(unsigned int irq, int apic, int pin)
        entry->pin = pin;
 }
 
+/*
+ * Reroute an IRQ to a different pin.
+ */
+static void __init replace_pin_at_irq(unsigned int irq,
+                                     int oldapic, int oldpin,
+                                     int newapic, int newpin)
+{
+       struct irq_pin_list *entry = irq_2_pin + irq;
+
+       while (1) {
+               if (entry->apic == oldapic && entry->pin == oldpin) {
+                       entry->apic = newapic;
+                       entry->pin = newpin;
+               }
+               if (!entry->next)
+                       break;
+               entry = irq_2_pin + entry->next;
+       }
+}
+
 #define __DO_ACTION(R, ACTION, FINAL)                                  \
                                                                        \
 {                                                                      \
@@ -156,6 +189,66 @@ static void clear_IO_APIC (void)
                        clear_IO_APIC_pin(apic, pin);
 }
 
+/*
+ * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to
+ * specific CPU-side IRQs.
+ */
+
+#define MAX_PIRQS 8
+int pirq_entries [MAX_PIRQS];
+int pirqs_enabled;
+
+int skip_ioapic_setup;
+#if 0
+
+static int __init noioapic_setup(char *str)
+{
+       skip_ioapic_setup = 1;
+       return 1;
+}
+
+__setup("noapic", noioapic_setup);
+
+static int __init ioapic_setup(char *str)
+{
+       skip_ioapic_setup = 0;
+       return 1;
+}
+
+__setup("apic", ioapic_setup);
+
+
+
+static int __init ioapic_pirq_setup(char *str)
+{
+       int i, max;
+       int ints[MAX_PIRQS+1];
+
+       get_options(str, ARRAY_SIZE(ints), ints);
+
+       for (i = 0; i < MAX_PIRQS; i++)
+               pirq_entries[i] = -1;
+
+       pirqs_enabled = 1;
+       printk(KERN_INFO "PIRQ redirection, working around broken MP-BIOS.\n");
+       max = MAX_PIRQS;
+       if (ints[0] < MAX_PIRQS)
+               max = ints[0];
+
+       for (i = 0; i < max; i++) {
+               printk(KERN_DEBUG "... PIRQ%d -> IRQ %d\n", i, ints[i+1]);
+               /*
+                * PIRQs are mapped upside down, usually.
+                */
+               pirq_entries[MAX_PIRQS-i-1] = ints[i+1];
+       }
+       return 1;
+}
+
+__setup("pirq=", ioapic_pirq_setup);
+
+#endif
+
 /*
  * Find the IRQ entry number of a certain pin.
  */
@@ -206,7 +299,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
 
        Dprintk("querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n",
                bus, slot, pin);
-       if (mp_bus_id_to_pci_bus[bus] == -1) {
+       if ((mp_bus_id_to_pci_bus==NULL) || (mp_bus_id_to_pci_bus[bus] == -1)) {
                printk(KERN_WARNING "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
                return -1;
        }
@@ -466,6 +559,20 @@ static int pin_2_irq(int idx, int apic, int pin)
                }
        }
 
+       /*
+        * PCI IRQ command line redirection. Yes, limits are hardcoded.
+        */
+       if ((pin >= 16) && (pin <= 23)) {
+               if (pirq_entries[pin-16] != -1) {
+                       if (!pirq_entries[pin-16]) {
+                               printk(KERN_DEBUG "disabling PIRQ%d\n", pin-16);
+                       } else {
+                               irq = pirq_entries[pin-16];
+                               printk(KERN_DEBUG "using PIRQ%d -> IRQ %d\n",
+                                               pin-16, irq);
+                       }
+               }
+       }
        return irq;
 }
 
@@ -495,11 +602,17 @@ static int __init assign_irq_vector(int irq)
                return IO_APIC_VECTOR(irq);
 next:
        current_vector += 8;
+
         /* XXX Skip the guestOS -> Xen syscall vector! XXX */
        if (current_vector == HYPERVISOR_CALL_VECTOR) goto next;
         /* XXX Skip the Linux/BSD fast-trap vector! XXX */
         if (current_vector == 0x80) goto next;
 
+#if 0
+       if (current_vector == SYSCALL_VECTOR)
+               goto next;
+#endif
+
        if (current_vector > FIRST_SYSTEM_VECTOR) {
                offset++;
                current_vector = FIRST_DEVICE_VECTOR + offset;
@@ -532,10 +645,10 @@ void __init setup_IO_APIC_irqs(void)
                 */
                memset(&entry,0,sizeof(entry));
 
-               entry.delivery_mode = dest_LowestPrio;
-               entry.dest_mode = INT_DELIVERY_MODE;
+               entry.delivery_mode = INT_DELIVERY_MODE;
+               entry.dest_mode = (INT_DEST_ADDR_MODE != 0);
                entry.mask = 0;                         /* enable IRQ */
-               entry.dest.logical.logical_dest = TARGET_CPUS;
+               entry.dest.logical.logical_dest = target_cpus();
 
                idx = find_irq_entry(apic,pin,mp_INT);
                if (idx == -1) {
@@ -553,11 +666,18 @@ void __init setup_IO_APIC_irqs(void)
                if (irq_trigger(idx)) {
                        entry.trigger = 1;
                        entry.mask = 1;
-                       entry.dest.logical.logical_dest = TARGET_CPUS;
                }
 
                irq = pin_2_irq(idx, apic, pin);
-               add_pin_to_irq(irq, apic, pin);
+               /*
+                * skip adding the timer int on secondary nodes, which causes
+                * a small but painful rift in the time-space continuum
+                */
+               if ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ) 
+                       && (apic != 0) && (irq == 0))
+                       continue;
+               else
+                       add_pin_to_irq(irq, apic, pin);
 
                if (!apic && !IO_APIC_IRQ(irq))
                        continue;
@@ -607,16 +727,16 @@ void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
         * We use logical delivery to get the timer IRQ
         * to the first CPU.
         */
-       entry.dest_mode = INT_DELIVERY_MODE;
+       entry.dest_mode = (INT_DEST_ADDR_MODE != 0);
        entry.mask = 0;                                 /* unmask IRQ now */
-       entry.dest.logical.logical_dest = TARGET_CPUS;
-       entry.delivery_mode = dest_LowestPrio;
+       entry.dest.logical.logical_dest = target_cpus();
+       entry.delivery_mode = INT_DELIVERY_MODE;
        entry.polarity = 0;
        entry.trigger = 0;
        entry.vector = vector;
 
        /*
-        * The timer IRQ doesnt have to know that behind the
+        * The timer IRQ doesn't have to know that behind the
         * scene we have a 8259A-master in AEOI mode ...
         */
        irq_desc[0].handler = &ioapic_edge_irq_type;
@@ -634,8 +754,9 @@ void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
 
 void __init UNEXPECTED_IO_APIC(void)
 {
-       printk(KERN_WARNING " WARNING: unexpected IO-APIC, please mail\n");
-       printk(KERN_WARNING "          to linux-smp@vger.kernel.org\n");
+       printk(KERN_WARNING 
+               "An unexpected IO-APIC was found. If this kernel release is less than\n"
+               "three months old please report this to linux-smp@vger.kernel.org\n");
 }
 
 void __init print_IO_APIC(void)
@@ -667,7 +788,7 @@ void __init print_IO_APIC(void)
        spin_unlock_irqrestore(&ioapic_lock, flags);
 
        printk("\n");
-       printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid);
+       printk(KERN_DEBUG "IO APIC #%d..XXXX....\n", mp_ioapics[apic].mpc_apicid);
        printk(KERN_DEBUG ".... register #00: %08X\n", *(int *)&reg_00);
        printk(KERN_DEBUG ".......    : physical APIC id: %02X\n", reg_00.ID);
        if (reg_00.__reserved_1 || reg_00.__reserved_2)
@@ -688,6 +809,7 @@ void __init print_IO_APIC(void)
        printk(KERN_DEBUG ".......     : PRQ implemented: %X\n", reg_01.PRQ);
        printk(KERN_DEBUG ".......     : IO APIC version: %04X\n", reg_01.version);
        if (    (reg_01.version != 0x01) && /* 82489DX IO-APICs */
+               (reg_01.version != 0x02) && /* VIA */
                (reg_01.version != 0x10) && /* oldest IO-APICs */
                (reg_01.version != 0x11) && /* Pentium/Pro IO-APICs */
                (reg_01.version != 0x13) && /* Xeon IO-APICs */
@@ -898,6 +1020,9 @@ static void __init enable_IO_APIC(void)
                irq_2_pin[i].pin = -1;
                irq_2_pin[i].next = 0;
        }
+       if (!pirqs_enabled)
+               for (i = 0; i < MAX_PIRQS; i++)
+                       pirq_entries[i] = -1;
 
        /*
         * The number of IO-APIC IRQ registers (== #pins):
@@ -944,6 +1069,9 @@ static void __init setup_ioapic_ids_from_mpc (void)
        unsigned char old_id;
        unsigned long flags;
 
+       if (clustered_apic_mode)
+               /* We don't have a good way to do this yet - hack */
+               phys_id_present_map = (u_long) 0xf;
        /*
         * Set the IOAPIC ID to the value stored in the MPC table.
         */
@@ -956,7 +1084,7 @@ static void __init setup_ioapic_ids_from_mpc (void)
                
                old_id = mp_ioapics[apic].mpc_apicid;
 
-               if (mp_ioapics[apic].mpc_apicid >= 0xf) {
+               if (mp_ioapics[apic].mpc_apicid >= apic_broadcast_id) {
                        printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
                                apic, mp_ioapics[apic].mpc_apicid);
                        printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
@@ -968,14 +1096,16 @@ static void __init setup_ioapic_ids_from_mpc (void)
                 * Sanity check, is the ID really free? Every APIC in a
                 * system must have a unique ID or we get lots of nice
                 * 'stuck on smp_invalidate_needed IPI wait' messages.
+                * I/O APIC IDs no longer have any meaning for xAPICs and SAPICs.
                 */
-               if (phys_id_present_map & (1 << mp_ioapics[apic].mpc_apicid)) {
+               if ((clustered_apic_mode != CLUSTERED_APIC_XAPIC) &&
+                   (phys_id_present_map & (1 << mp_ioapics[apic].mpc_apicid))) {
                        printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
                                apic, mp_ioapics[apic].mpc_apicid);
                        for (i = 0; i < 0xf; i++)
                                if (!(phys_id_present_map & (1 << i)))
                                        break;
-                       if (i >= 0xf)
+                       if (i >= apic_broadcast_id)
                                panic("Max APIC ID exceeded!\n");
                        printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
                                i);
@@ -1170,6 +1300,10 @@ static void end_level_ioapic_irq (unsigned int irq)
 #ifdef APIC_LOCKUP_DEBUG
                struct irq_pin_list *entry;
 #endif
+
+#ifdef APIC_MISMATCH_DEBUG
+               atomic_inc(&irq_mis_count);
+#endif
                spin_lock(&ioapic_lock);
                __mask_and_edge_IO_APIC_irq(irq);
 #ifdef APIC_LOCKUP_DEBUG
@@ -1302,6 +1436,36 @@ static struct hw_interrupt_type lapic_irq_type = {
        end_lapic_irq
 };
 
+static void enable_NMI_through_LVT0 (void * dummy)
+{
+       unsigned int v, ver;
+
+       ver = apic_read(APIC_LVR);
+       ver = GET_APIC_VERSION(ver);
+       v = APIC_DM_NMI;                        /* unmask and set to NMI */
+       if (!APIC_INTEGRATED(ver))              /* 82489DX */
+               v |= APIC_LVT_LEVEL_TRIGGER;
+       apic_write_around(APIC_LVT0, v);
+}
+
+static void setup_nmi (void)
+{
+       /*
+        * Dirty trick to enable the NMI watchdog ...
+        * We put the 8259A master into AEOI mode and
+        * unmask on all local APICs LVT0 as NMI.
+        *
+        * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire')
+        * is from Maciej W. Rozycki - so we do not have to EOI from
+        * the NMI handler or the timer interrupt.
+        */ 
+       printk(KERN_INFO "activating NMI Watchdog ...");
+
+       smp_call_function(enable_NMI_through_LVT0, NULL, 1, 1);
+       enable_NMI_through_LVT0(NULL);
+
+       printk(" done.\n");
+}
 
 /*
  * This looks a bit hackish but it's about the only one way of sending
@@ -1407,6 +1571,12 @@ static inline void check_timer(void)
                 */
                unmask_IO_APIC_irq(0);
                if (timer_irq_works()) {
+                       if (nmi_watchdog == NMI_IO_APIC) {
+                               disable_8259A_irq(0);
+                               setup_nmi();
+                               enable_8259A_irq(0);
+                               // XXX Xen check_nmi_watchdog();
+                       }
                        return;
                }
                clear_IO_APIC_pin(0, pin1);
@@ -1422,6 +1592,14 @@ static inline void check_timer(void)
                setup_ExtINT_IRQ0_pin(pin2, vector);
                if (timer_irq_works()) {
                        printk("works.\n");
+                       if (pin1 != -1)
+                               replace_pin_at_irq(0, 0, pin1, 0, pin2);
+                       else
+                               add_pin_to_irq(0, 0, pin2);
+                       if (nmi_watchdog == NMI_IO_APIC) {
+                               setup_nmi();
+                               // XXX Xen check_nmi_watchdog();
+                       }
                        return;
                }
                /*
@@ -1431,6 +1609,11 @@ static inline void check_timer(void)
        }
        printk(" failed.\n");
 
+       if (nmi_watchdog) {
+               printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
+               nmi_watchdog = 0;
+       }
+
        printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
 
        disable_8259A_irq(0);
@@ -1462,10 +1645,19 @@ static inline void check_timer(void)
 }
 
 /*
+ *
  * IRQ's that are handled by the old PIC in all cases:
  * - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ.
  *   Linux doesn't really care, as it's not actually used
  *   for any interrupt handling anyway.
+ * - There used to be IRQ13 here as well, but all
+ *   MPS-compliant must not use it for FPU coupling and we
+ *   want to use exception 16 anyway.  And there are
+ *   systems who connect it to an I/O APIC for other uses.
+ *   Thus we don't mark it special any longer.
+ *
+ * Additionally, something is definitely wrong with irq9
+ * on PIIX4 boards.
  */
 #define PIC_IRQS       (1<<2)
 
index c5cf58a3129922412aa6b1e5e62e756227cee01a..4f0edeea0e8d3bdd668150c4e158befe9cade2c0 100644 (file)
 #include <xeno/smp.h>
 #include <asm/mpspec.h>
 #include <asm/pgalloc.h>
+#include <asm/smpboot.h>
+#include <xeno/kernel.h>
+
+int numnodes = 1; /* XXX Xen */
 
 /* Have we found an MP table */
 int smp_found_config;
@@ -29,16 +33,20 @@ int smp_found_config;
  * MP-table.
  */
 int apic_version [MAX_APICS];
-int mp_bus_id_to_type [MAX_MP_BUSSES];
-int mp_bus_id_to_node [MAX_MP_BUSSES];
-int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
+int quad_local_to_mp_bus_id [NR_CPUS/4][4];
 int mp_current_pci_id;
+int *mp_bus_id_to_type;
+int *mp_bus_id_to_node;
+int *mp_bus_id_to_local;
+int *mp_bus_id_to_pci_bus;
+int max_mp_busses;
+int max_irq_sources;
 
 /* I/O APIC entries */
 struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
 
 /* # of MP IRQ source entries */
-struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
+struct mpc_config_intsrc *mp_irqs;
 
 /* MP IRQ source entries */
 int mp_irq_entries;
@@ -56,23 +64,32 @@ static unsigned int num_processors;
 
 /* Bitmask of physically existing CPUs */
 unsigned long phys_cpu_present_map;
+unsigned long logical_cpu_present_map;
+
+#ifdef CONFIG_X86_CLUSTERED_APIC
+unsigned char esr_disable = 0;
+unsigned char clustered_apic_mode = CLUSTERED_APIC_NONE;
+unsigned int apic_broadcast_id = APIC_BROADCAST_ID_APIC;
+#endif
+unsigned char raw_phys_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
 
 /*
  * Intel MP BIOS table parsing routines:
  */
 
+#ifndef CONFIG_X86_VISWS_APIC
 /*
  * Checksum an MP configuration block.
  */
 
 static int __init mpf_checksum(unsigned char *mp, int len)
 {
-    int sum = 0;
+       int sum = 0;
 
-    while (len--)
-        sum += *mp++;
+       while (len--)
+               sum += *mp++;
 
-    return sum & 0xFF;
+       return sum & 0xFF;
 }
 
 /*
@@ -81,38 +98,47 @@ static int __init mpf_checksum(unsigned char *mp, int len)
 
 static char __init *mpc_family(int family,int model)
 {
-    static char n[32];
-    static char *model_defs[]=
-    {
-        "80486DX","80486DX",
-        "80486SX","80486DX/2 or 80487",
-        "80486SL","80486SX/2",
-        "Unknown","80486DX/2-WB",
-        "80486DX/4","80486DX/4-WB"
-    };
-
-    switch (family) {
-    case 0x04:
-        if (model < 10)
-            return model_defs[model];
-        break;
-
-    case 0x05:
-        return("Pentium(tm)");
-
-    case 0x06:
-        return("Pentium(tm) Pro");
-
-    case 0x0F:
-        if (model == 0x00)
-            return("Pentium 4(tm)");
-        if (model == 0x0F)
-            return("Special controller");
-    }
-    sprintf(n,"Unknown CPU [%d:%d]",family, model);
-    return n;
+       static char n[32];
+       static char *model_defs[]=
+       {
+               "80486DX","80486DX",
+               "80486SX","80486DX/2 or 80487",
+               "80486SL","80486SX/2",
+               "Unknown","80486DX/2-WB",
+               "80486DX/4","80486DX/4-WB"
+       };
+
+       switch (family) {
+               case 0x04:
+                       if (model < 10)
+                               return model_defs[model];
+                       break;
+
+               case 0x05:
+                       return("Pentium(tm)");
+
+               case 0x06:
+                       return("Pentium(tm) Pro");
+
+               case 0x0F:
+                       if (model == 0x00)
+                               return("Pentium 4(tm)");
+                       if (model == 0x02)
+                               return("Pentium 4(tm) XEON(tm)");
+                       if (model == 0x0F)
+                               return("Special controller");
+       }
+       sprintf(n,"Unknown CPU [%d:%d]",family, model);
+       return n;
 }
 
+#ifdef CONFIG_X86_IO_APIC
+// XXX Xen extern int have_acpi_tables;        /* set by acpitable.c */
+#define have_acpi_tables (0)
+#else
+#define have_acpi_tables (0)
+#endif
+
 /* 
  * Have to match translation table entries to main table entries by counter
  * hence the mpc_record variable .... can't see a less disgusting way of
@@ -120,127 +146,256 @@ static char __init *mpc_family(int family,int model)
  */
 
 static int mpc_record; 
+static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata;
 
 void __init MP_processor_info (struct mpc_config_processor *m)
 {
-    int ver, logical_apicid;
+       int ver, quad, logical_apicid;
        
-    if (!(m->mpc_cpuflag & CPU_ENABLED))
-        return;
-
-    logical_apicid = m->mpc_apicid;
-    printk("Processor #%d %s APIC version %d\n",
-           m->mpc_apicid,
-           mpc_family((m->mpc_cpufeature & CPU_FAMILY_MASK)>>8 ,
-                      (m->mpc_cpufeature & CPU_MODEL_MASK)>>4),
-           m->mpc_apicver);
-
-    if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
-        Dprintk("    Bootup CPU\n");
-        boot_cpu_physical_apicid = m->mpc_apicid;
-        boot_cpu_logical_apicid = logical_apicid;
-    }
-
-    num_processors++;
-
-    if (m->mpc_apicid > MAX_APICS) {
-        printk("Processor #%d INVALID. (Max ID: %d).\n",
-               m->mpc_apicid, MAX_APICS);
-        return;
-    }
-    ver = m->mpc_apicver;
-
-    phys_cpu_present_map |= 1 << m->mpc_apicid;
-
-    /*
-     * Validate version
-     */
-    if (ver == 0x0) {
-        printk("BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid);
-        ver = 0x10;
-    }
-    apic_version[m->mpc_apicid] = ver;
+       if (!(m->mpc_cpuflag & CPU_ENABLED))
+               return;
+
+       logical_apicid = m->mpc_apicid;
+       if (clustered_apic_mode == CLUSTERED_APIC_NUMAQ) {
+               quad = translation_table[mpc_record]->trans_quad;
+               logical_apicid = (quad << 4) + 
+                       (m->mpc_apicid ? m->mpc_apicid << 1 : 1);
+               printk("Processor #%d %s APIC version %d (quad %d, apic %d)\n",
+                       m->mpc_apicid,
+                       mpc_family((m->mpc_cpufeature & CPU_FAMILY_MASK)>>8 ,
+                                  (m->mpc_cpufeature & CPU_MODEL_MASK)>>4),
+                       m->mpc_apicver, quad, logical_apicid);
+       } else {
+               printk("Processor #%d %s APIC version %d\n",
+                       m->mpc_apicid,
+                       mpc_family((m->mpc_cpufeature & CPU_FAMILY_MASK)>>8 ,
+                                  (m->mpc_cpufeature & CPU_MODEL_MASK)>>4),
+                       m->mpc_apicver);
+       }
+
+       if (m->mpc_featureflag&(1<<0))
+               Dprintk("    Floating point unit present.\n");
+       if (m->mpc_featureflag&(1<<7))
+               Dprintk("    Machine Exception supported.\n");
+       if (m->mpc_featureflag&(1<<8))
+               Dprintk("    64 bit compare & exchange supported.\n");
+       if (m->mpc_featureflag&(1<<9))
+               Dprintk("    Internal APIC present.\n");
+       if (m->mpc_featureflag&(1<<11))
+               Dprintk("    SEP present.\n");
+       if (m->mpc_featureflag&(1<<12))
+               Dprintk("    MTRR  present.\n");
+       if (m->mpc_featureflag&(1<<13))
+               Dprintk("    PGE  present.\n");
+       if (m->mpc_featureflag&(1<<14))
+               Dprintk("    MCA  present.\n");
+       if (m->mpc_featureflag&(1<<15))
+               Dprintk("    CMOV  present.\n");
+       if (m->mpc_featureflag&(1<<16))
+               Dprintk("    PAT  present.\n");
+       if (m->mpc_featureflag&(1<<17))
+               Dprintk("    PSE  present.\n");
+       if (m->mpc_featureflag&(1<<18))
+               Dprintk("    PSN  present.\n");
+       if (m->mpc_featureflag&(1<<19))
+               Dprintk("    Cache Line Flush Instruction present.\n");
+       /* 20 Reserved */
+       if (m->mpc_featureflag&(1<<21))
+               Dprintk("    Debug Trace and EMON Store present.\n");
+       if (m->mpc_featureflag&(1<<22))
+               Dprintk("    ACPI Thermal Throttle Registers  present.\n");
+       if (m->mpc_featureflag&(1<<23))
+               Dprintk("    MMX  present.\n");
+       if (m->mpc_featureflag&(1<<24))
+               Dprintk("    FXSR  present.\n");
+       if (m->mpc_featureflag&(1<<25))
+               Dprintk("    XMM  present.\n");
+       if (m->mpc_featureflag&(1<<26))
+               Dprintk("    Willamette New Instructions  present.\n");
+       if (m->mpc_featureflag&(1<<27))
+               Dprintk("    Self Snoop  present.\n");
+       if (m->mpc_featureflag&(1<<28))
+               Dprintk("    HT  present.\n");
+       if (m->mpc_featureflag&(1<<29))
+               Dprintk("    Thermal Monitor present.\n");
+       /* 30, 31 Reserved */
+
+
+       if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
+               Dprintk("    Bootup CPU\n");
+               boot_cpu_physical_apicid = m->mpc_apicid;
+               boot_cpu_logical_apicid = logical_apicid;
+       }
+
+       num_processors++;
+
+       if (m->mpc_apicid > MAX_APICS) {
+               printk("Processor #%d INVALID. (Max ID: %d).\n",
+                       m->mpc_apicid, MAX_APICS);
+               --num_processors;
+               return;
+       }
+       ver = m->mpc_apicver;
+
+       logical_cpu_present_map |= 1 << (num_processors-1);
+       phys_cpu_present_map |= apicid_to_phys_cpu_present(m->mpc_apicid);
+       /*
+        * Validate version
+        */
+       if (ver == 0x0) {
+               printk("BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid);
+               ver = 0x10;
+       }
+       apic_version[m->mpc_apicid] = ver;
+       raw_phys_apicid[num_processors - 1] = m->mpc_apicid;
 }
 
 static void __init MP_bus_info (struct mpc_config_bus *m)
 {
-    char str[7];
+       char str[7];
+       int quad;
 
-    memcpy(str, m->mpc_bustype, 6);
-    str[6] = 0;
+       memcpy(str, m->mpc_bustype, 6);
+       str[6] = 0;
        
-    Dprintk("Bus #%d is %s\n", m->mpc_busid, str);
-
-    if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) {
-        mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
-    } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) {
-        mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA;
-    } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0) {
-        mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI;
-        mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id;
-        mp_current_pci_id++;
-    } else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) {
-        mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA;
-    } else {
-        printk("Unknown bustype %s - ignoring\n", str);
-    }
+       if (clustered_apic_mode == CLUSTERED_APIC_NUMAQ) {
+               quad = translation_table[mpc_record]->trans_quad;
+               mp_bus_id_to_node[m->mpc_busid] = quad;
+               mp_bus_id_to_local[m->mpc_busid] = translation_table[mpc_record]->trans_local;
+               quad_local_to_mp_bus_id[quad][translation_table[mpc_record]->trans_local] = m->mpc_busid;
+               printk("Bus #%d is %s (node %d)\n", m->mpc_busid, str, quad);
+       } else {
+               Dprintk("Bus #%d is %s\n", m->mpc_busid, str);
+       }
+
+       if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) {
+               mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
+       } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) {
+               mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA;
+       } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0) {
+               mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI;
+               mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id;
+               mp_current_pci_id++;
+       } else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) {
+               mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA;
+       } else {
+               printk("Unknown bustype %s - ignoring\n", str);
+       }
 }
 
 static void __init MP_ioapic_info (struct mpc_config_ioapic *m)
 {
-    if (!(m->mpc_flags & MPC_APIC_USABLE))
-        return;
-
-    printk("I/O APIC #%d Version %d at 0x%lX.\n",
-           m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr);
-    if (nr_ioapics >= MAX_IO_APICS) {
-        printk("Max # of I/O APICs (%d) exceeded (found %d).\n",
-               MAX_IO_APICS, nr_ioapics);
-        panic("Recompile kernel with bigger MAX_IO_APICS!.\n");
-    }
-    if (!m->mpc_apicaddr) {
-        printk("WARNING: bogus zero I/O APIC address"
-               " found in MP table, skipping!\n");
-        return;
-    }
-    mp_ioapics[nr_ioapics] = *m;
-    nr_ioapics++;
+       if (!(m->mpc_flags & MPC_APIC_USABLE))
+               return;
+
+       printk("I/O APIC #%d Version %d at 0x%lX.\n",
+               m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr);
+       if (nr_ioapics >= MAX_IO_APICS) {
+               printk("Max # of I/O APICs (%d) exceeded (found %d).\n",
+                       MAX_IO_APICS, nr_ioapics);
+               panic("Recompile kernel with bigger MAX_IO_APICS!.\n");
+       }
+       if (!m->mpc_apicaddr) {
+               printk(KERN_ERR "WARNING: bogus zero I/O APIC address"
+                       " found in MP table, skipping!\n");
+               return;
+       }
+       mp_ioapics[nr_ioapics] = *m;
+       nr_ioapics++;
 }
 
 static void __init MP_intsrc_info (struct mpc_config_intsrc *m)
 {
-    mp_irqs [mp_irq_entries] = *m;
-    Dprintk("Int: type %d, pol %d, trig %d, bus %d,"
-            " IRQ %02x, APIC ID %x, APIC INT %02x\n",
-            m->mpc_irqtype, m->mpc_irqflag & 3,
-            (m->mpc_irqflag >> 2) & 3, m->mpc_srcbus,
-            m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq);
-    if (++mp_irq_entries == MAX_IRQ_SOURCES)
-        panic("Max # of irq sources exceeded!!\n");
+       mp_irqs [mp_irq_entries] = *m;
+       Dprintk("Int: type %d, pol %d, trig %d, bus %d,"
+               " IRQ %02x, APIC ID %x, APIC INT %02x\n",
+                       m->mpc_irqtype, m->mpc_irqflag & 3,
+                       (m->mpc_irqflag >> 2) & 3, m->mpc_srcbus,
+                       m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq);
+       if (++mp_irq_entries == max_irq_sources)
+               panic("Max # of irq sources exceeded!!\n");
 }
 
 static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m)
 {
-    Dprintk("Lint: type %d, pol %d, trig %d, bus %d,"
-            " IRQ %02x, APIC ID %x, APIC LINT %02x\n",
-            m->mpc_irqtype, m->mpc_irqflag & 3,
-            (m->mpc_irqflag >> 2) &3, m->mpc_srcbusid,
-            m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint);
-    /*
-     * Well it seems all SMP boards in existence
-     * use ExtINT/LVT1 == LINT0 and
-     * NMI/LVT2 == LINT1 - the following check
-     * will show us if this assumptions is false.
-     * Until then we do not have to add baggage.
-     */
-    if ((m->mpc_irqtype == mp_ExtINT) &&
-        (m->mpc_destapiclint != 0))
-        BUG();
-    if ((m->mpc_irqtype == mp_NMI) &&
-        (m->mpc_destapiclint != 1))
-        BUG();
+       Dprintk("Lint: type %d, pol %d, trig %d, bus %d,"
+               " IRQ %02x, APIC ID %x, APIC LINT %02x\n",
+                       m->mpc_irqtype, m->mpc_irqflag & 3,
+                       (m->mpc_irqflag >> 2) &3, m->mpc_srcbusid,
+                       m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint);
+       /*
+        * Well it seems all SMP boards in existence
+        * use ExtINT/LVT1 == LINT0 and
+        * NMI/LVT2 == LINT1 - the following check
+        * will show us if this assumptions is false.
+        * Until then we do not have to add baggage.
+        */
+       if ((m->mpc_irqtype == mp_ExtINT) &&
+               (m->mpc_destapiclint != 0))
+                       BUG();
+       if ((m->mpc_irqtype == mp_NMI) &&
+               (m->mpc_destapiclint != 1))
+                       BUG();
 }
 
+static void __init MP_translation_info (struct mpc_config_translation *m)
+{
+       printk("Translation: record %d, type %d, quad %d, global %d, local %d\n", mpc_record, m->trans_type, m->trans_quad, m->trans_global, m->trans_local);
+
+       if (mpc_record >= MAX_MPC_ENTRY) 
+               printk("MAX_MPC_ENTRY exceeded!\n");
+       else
+               translation_table[mpc_record] = m; /* stash this for later */
+       if (m->trans_quad+1 > numnodes)
+               numnodes = m->trans_quad+1;
+}
+
+/*
+ * Read/parse the MPC oem tables
+ */
+
+static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable, \
+       unsigned short oemsize)
+{
+       int count = sizeof (*oemtable); /* the header size */
+       unsigned char *oemptr = ((unsigned char *)oemtable)+count;
+       
+       printk("Found an OEM MPC table at %8p - parsing it ... \n", oemtable);
+       if (memcmp(oemtable->oem_signature,MPC_OEM_SIGNATURE,4))
+       {
+               printk("SMP mpc oemtable: bad signature [%c%c%c%c]!\n",
+                       oemtable->oem_signature[0],
+                       oemtable->oem_signature[1],
+                       oemtable->oem_signature[2],
+                       oemtable->oem_signature[3]);
+               return;
+       }
+       if (mpf_checksum((unsigned char *)oemtable,oemtable->oem_length))
+       {
+               printk("SMP oem mptable: checksum error!\n");
+               return;
+       }
+       while (count < oemtable->oem_length) {
+               switch (*oemptr) {
+                       case MP_TRANSLATION:
+                       {
+                               struct mpc_config_translation *m=
+                                       (struct mpc_config_translation *)oemptr;
+                               MP_translation_info(m);
+                               oemptr += sizeof(*m);
+                               count += sizeof(*m);
+                               ++mpc_record;
+                               break;
+                       }
+                       default:
+                       {
+                               printk("Unrecognised OEM table entry type! - %d\n", (int) *oemptr);
+                               return;
+                       }
+               }
+       }
+}
 
 /*
  * Read/parse the MPC
@@ -248,383 +403,542 @@ static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m)
 
 static int __init smp_read_mpc(struct mp_config_table *mpc)
 {
-    char str[16];
-    int count=sizeof(*mpc);
-    unsigned char *mpt=((unsigned char *)mpc)+count;
-
-    if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) {
-        panic("SMP mptable: bad signature [%c%c%c%c]!\n",
-              mpc->mpc_signature[0],
-              mpc->mpc_signature[1],
-              mpc->mpc_signature[2],
-              mpc->mpc_signature[3]);
-        return 0;
-    }
-    if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) {
-        panic("SMP mptable: checksum error!\n");
-        return 0;
-    }
-    if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) {
-        printk("SMP mptable: bad table version (%d)!!\n",
-               mpc->mpc_spec);
-        return 0;
-    }
-    if (!mpc->mpc_lapic) {
-        printk("SMP mptable: null local APIC address!\n");
-        return 0;
-    }
-    memcpy(str,mpc->mpc_oem,8);
-    str[8]=0;
-    printk("OEM ID: %s ",str);
-
-    memcpy(str,mpc->mpc_productid,12);
-    str[12]=0;
-    printk("Product ID: %s ",str);
-
-    printk("APIC at: 0x%lX\n", mpc->mpc_lapic);
-
-    /* save the local APIC address, it might be non-default. */
-    mp_lapic_addr = mpc->mpc_lapic;
-
-    /*
-     * Now process the configuration blocks.
-     */
-    while (count < mpc->mpc_length) {
-        switch(*mpt) {
-        case MP_PROCESSOR:
-        {
-            struct mpc_config_processor *m=
-                (struct mpc_config_processor *)mpt;
-
-            MP_processor_info(m);
-            mpt += sizeof(*m);
-            count += sizeof(*m);
-            break;
-        }
-        case MP_BUS:
-        {
-            struct mpc_config_bus *m=
-                (struct mpc_config_bus *)mpt;
-            MP_bus_info(m);
-            mpt += sizeof(*m);
-            count += sizeof(*m);
-            break;
-        }
-        case MP_IOAPIC:
-        {
-            struct mpc_config_ioapic *m=
-                (struct mpc_config_ioapic *)mpt;
-            MP_ioapic_info(m);
-            mpt+=sizeof(*m);
-            count+=sizeof(*m);
-            break;
-        }
-        case MP_INTSRC:
-        {
-            struct mpc_config_intsrc *m=
-                (struct mpc_config_intsrc *)mpt;
-
-            MP_intsrc_info(m);
-            mpt+=sizeof(*m);
-            count+=sizeof(*m);
-            break;
-        }
-        case MP_LINTSRC:
-        {
-            struct mpc_config_lintsrc *m=
-                (struct mpc_config_lintsrc *)mpt;
-            MP_lintsrc_info(m);
-            mpt+=sizeof(*m);
-            count+=sizeof(*m);
-            break;
-        }
-        default:
-        {
-            count = mpc->mpc_length;
-            break;
-        }
-        }
-        ++mpc_record;
-    }
-
-    if (!num_processors)
-        printk("SMP mptable: no processors registered!\n");
-    return num_processors;
+       char oem[16], prod[14];
+       int count=sizeof(*mpc);
+       unsigned char *mpt=((unsigned char *)mpc)+count;
+       int num_bus = 0;
+       int num_irq = 0;
+       unsigned char *bus_data;
+
+       if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) {
+               panic("SMP mptable: bad signature [%c%c%c%c]!\n",
+                       mpc->mpc_signature[0],
+                       mpc->mpc_signature[1],
+                       mpc->mpc_signature[2],
+                       mpc->mpc_signature[3]);
+               return 0;
+       }
+       if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) {
+               panic("SMP mptable: checksum error!\n");
+               return 0;
+       }
+       if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) {
+               printk(KERN_ERR "SMP mptable: bad table version (%d)!!\n",
+                       mpc->mpc_spec);
+               return 0;
+       }
+       if (!mpc->mpc_lapic) {
+               printk(KERN_ERR "SMP mptable: null local APIC address!\n");
+               return 0;
+       }
+       memcpy(oem,mpc->mpc_oem,8);
+       oem[8]=0;
+       printk("OEM ID: %s ",oem);
+
+       memcpy(prod,mpc->mpc_productid,12);
+       prod[12]=0;
+       printk("Product ID: %s ",prod);
+
+       detect_clustered_apic(oem, prod);
+       
+       printk("APIC at: 0x%lX\n",mpc->mpc_lapic);
+
+       /* save the local APIC address, it might be non-default,
+        * but only if we're not using the ACPI tables
+        */
+       if (!have_acpi_tables)
+               mp_lapic_addr = mpc->mpc_lapic;
+
+       if ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ) && mpc->mpc_oemptr) {
+               /* We need to process the oem mpc tables to tell us which quad things are in ... */
+               mpc_record = 0;
+               smp_read_mpc_oem((struct mp_config_oemtable *) mpc->mpc_oemptr, mpc->mpc_oemsize);
+               mpc_record = 0;
+       }
+
+       /* Pre-scan to determine the number of bus and 
+        * interrupts records we have
+        */
+       while (count < mpc->mpc_length) {
+               switch (*mpt) {
+                       case MP_PROCESSOR:
+                               mpt += sizeof(struct mpc_config_processor);
+                               count += sizeof(struct mpc_config_processor);
+                               break;
+                       case MP_BUS:
+                               ++num_bus;
+                               mpt += sizeof(struct mpc_config_bus);
+                               count += sizeof(struct mpc_config_bus);
+                               break;
+                       case MP_INTSRC:
+                               ++num_irq;
+                               mpt += sizeof(struct mpc_config_intsrc);
+                               count += sizeof(struct mpc_config_intsrc);
+                               break;
+                       case MP_IOAPIC:
+                               mpt += sizeof(struct mpc_config_ioapic);
+                               count += sizeof(struct mpc_config_ioapic);
+                               break;
+                       case MP_LINTSRC:
+                               mpt += sizeof(struct mpc_config_lintsrc);
+                               count += sizeof(struct mpc_config_lintsrc);
+                               break;
+                       default:
+                               count = mpc->mpc_length;
+                               break;
+               }
+       }
+       /* 
+        * Paranoia: Allocate one extra of both the number of busses and number
+        * of irqs, and make sure that we have at least 4 interrupts per PCI
+        * slot.  But some machines do not report very many busses, so we need
+        * to fall back on the older defaults.
+        */
+       ++num_bus;
+       max_mp_busses = max(num_bus, MAX_MP_BUSSES);
+       if (num_irq < (4 * max_mp_busses))
+               num_irq = 4 * num_bus;  /* 4 intr/PCI slot */
+       ++num_irq;
+       max_irq_sources = max(num_irq, MAX_IRQ_SOURCES);
+       
+       count = (max_mp_busses * sizeof(int)) * 4;
+       count += (max_irq_sources * sizeof(struct mpc_config_intsrc));
+       
+       {
+       //bus_data = alloc_bootmem(count);  XXX Xen
+       static char arr[4096];
+       if(count > 4096) BUG();
+       bus_data = (void*)arr;
+       
+       }
+       if (!bus_data) {
+               printk(KERN_ERR "SMP mptable: out of memory!\n");
+               return 0;
+       }
+       mp_bus_id_to_type = (int *)&bus_data[0];
+       mp_bus_id_to_node = (int *)&bus_data[(max_mp_busses * sizeof(int))];
+       mp_bus_id_to_local = (int *)&bus_data[(max_mp_busses * sizeof(int)) * 2];
+       mp_bus_id_to_pci_bus = (int *)&bus_data[(max_mp_busses * sizeof(int)) * 3];
+       mp_irqs = (struct mpc_config_intsrc *)&bus_data[(max_mp_busses * sizeof(int)) * 4];
+       memset(mp_bus_id_to_pci_bus, -1, max_mp_busses);
+
+       /*
+        *      Now process the configuration blocks.
+        */
+       count = sizeof(*mpc);
+       mpt = ((unsigned char *)mpc)+count;
+       while (count < mpc->mpc_length) {
+               switch(*mpt) {
+                       case MP_PROCESSOR:
+                       {
+                               struct mpc_config_processor *m=
+                                       (struct mpc_config_processor *)mpt;
+
+                               /* ACPI may already have provided this one for us */
+                               if (!have_acpi_tables)
+                                       MP_processor_info(m);
+                               mpt += sizeof(*m);
+                               count += sizeof(*m);
+                               break;
+                       }
+                       case MP_BUS:
+                       {
+                               struct mpc_config_bus *m=
+                                       (struct mpc_config_bus *)mpt;
+                               MP_bus_info(m);
+                               mpt += sizeof(*m);
+                               count += sizeof(*m);
+                               break;
+                       }
+                       case MP_IOAPIC:
+                       {
+                               struct mpc_config_ioapic *m=
+                                       (struct mpc_config_ioapic *)mpt;
+                               MP_ioapic_info(m);
+                               mpt+=sizeof(*m);
+                               count+=sizeof(*m);
+                               break;
+                       }
+                       case MP_INTSRC:
+                       {
+                               struct mpc_config_intsrc *m=
+                                       (struct mpc_config_intsrc *)mpt;
+
+                               MP_intsrc_info(m);
+                               mpt+=sizeof(*m);
+                               count+=sizeof(*m);
+                               break;
+                       }
+                       case MP_LINTSRC:
+                       {
+                               struct mpc_config_lintsrc *m=
+                                       (struct mpc_config_lintsrc *)mpt;
+                               MP_lintsrc_info(m);
+                               mpt+=sizeof(*m);
+                               count+=sizeof(*m);
+                               break;
+                       }
+                       default:
+                       {
+                               count = mpc->mpc_length;
+                               break;
+                       }
+               }
+               ++mpc_record;
+       }
+
+       if (clustered_apic_mode){
+               phys_cpu_present_map = logical_cpu_present_map;
+       }
+
+
+       printk("Enabling APIC mode: ");
+       if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
+               printk("Clustered Logical.      ");
+       else if(clustered_apic_mode == CLUSTERED_APIC_XAPIC)
+               printk("Physical.       ");
+       else
+               printk("Flat.   ");
+       printk("Using %d I/O APICs\n",nr_ioapics);
+
+       if (!num_processors)
+               printk(KERN_ERR "SMP mptable: no processors registered!\n");
+       return num_processors;
 }
 
 static int __init ELCR_trigger(unsigned int irq)
 {
-    unsigned int port;
+       unsigned int port;
 
-    port = 0x4d0 + (irq >> 3);
-    return (inb(port) >> (irq & 7)) & 1;
+       port = 0x4d0 + (irq >> 3);
+       return (inb(port) >> (irq & 7)) & 1;
 }
 
 static void __init construct_default_ioirq_mptable(int mpc_default_type)
 {
-    struct mpc_config_intsrc intsrc;
-    int i;
-    int ELCR_fallback = 0;
-
-    intsrc.mpc_type = MP_INTSRC;
-    intsrc.mpc_irqflag = 0;                    /* conforming */
-    intsrc.mpc_srcbus = 0;
-    intsrc.mpc_dstapic = mp_ioapics[0].mpc_apicid;
-
-    intsrc.mpc_irqtype = mp_INT;
-
-    /*
-     *  If true, we have an ISA/PCI system with no IRQ entries
-     *  in the MP table. To prevent the PCI interrupts from being set up
-     *  incorrectly, we try to use the ELCR. The sanity check to see if
-     *  there is good ELCR data is very simple - IRQ0, 1, 2 and 13 can
-     *  never be level sensitive, so we simply see if the ELCR agrees.
-     *  If it does, we assume it's valid.
-     */
-    if (mpc_default_type == 5) {
-        printk("ISA/PCI bus type with no IRQ information... falling back to ELCR\n");
-
-        if (ELCR_trigger(0) || ELCR_trigger(1) || ELCR_trigger(2) || ELCR_trigger(13))
-            printk("ELCR contains invalid data... not using ELCR\n");
-        else {
-            printk("Using ELCR to identify PCI interrupts\n");
-            ELCR_fallback = 1;
-        }
-    }
-
-    for (i = 0; i < 16; i++) {
-        switch (mpc_default_type) {
-        case 2:
-            if (i == 0 || i == 13)
-                continue;      /* IRQ0 & IRQ13 not connected */
-            /* fall through */
-        default:
-            if (i == 2)
-                continue;      /* IRQ2 is never connected */
-        }
-
-        if (ELCR_fallback) {
-            /*
-             *  If the ELCR indicates a level-sensitive interrupt, we
-             *  copy that information over to the MP table in the
-             *  irqflag field (level sensitive, active high polarity).
-             */
-            if (ELCR_trigger(i))
-                intsrc.mpc_irqflag = 13;
-            else
-                intsrc.mpc_irqflag = 0;
-        }
-
-        intsrc.mpc_srcbusirq = i;
-        intsrc.mpc_dstirq = i ? i : 2;         /* IRQ0 to INTIN2 */
-        MP_intsrc_info(&intsrc);
-    }
-
-    intsrc.mpc_irqtype = mp_ExtINT;
-    intsrc.mpc_srcbusirq = 0;
-    intsrc.mpc_dstirq = 0;                             /* 8259A to INTIN0 */
-    MP_intsrc_info(&intsrc);
+       struct mpc_config_intsrc intsrc;
+       int i;
+       int ELCR_fallback = 0;
+
+       intsrc.mpc_type = MP_INTSRC;
+       intsrc.mpc_irqflag = 0;                 /* conforming */
+       intsrc.mpc_srcbus = 0;
+       intsrc.mpc_dstapic = mp_ioapics[0].mpc_apicid;
+
+       intsrc.mpc_irqtype = mp_INT;
+
+       /*
+        *  If true, we have an ISA/PCI system with no IRQ entries
+        *  in the MP table. To prevent the PCI interrupts from being set up
+        *  incorrectly, we try to use the ELCR. The sanity check to see if
+        *  there is good ELCR data is very simple - IRQ0, 1, 2 and 13 can
+        *  never be level sensitive, so we simply see if the ELCR agrees.
+        *  If it does, we assume it's valid.
+        */
+       if (mpc_default_type == 5) {
+               printk("ISA/PCI bus type with no IRQ information... falling back to ELCR\n");
+
+               if (ELCR_trigger(0) || ELCR_trigger(1) || ELCR_trigger(2) || ELCR_trigger(13))
+                       printk("ELCR contains invalid data... not using ELCR\n");
+               else {
+                       printk("Using ELCR to identify PCI interrupts\n");
+                       ELCR_fallback = 1;
+               }
+       }
+
+       for (i = 0; i < 16; i++) {
+               switch (mpc_default_type) {
+               case 2:
+                       if (i == 0 || i == 13)
+                               continue;       /* IRQ0 & IRQ13 not connected */
+                       /* fall through */
+               default:
+                       if (i == 2)
+                               continue;       /* IRQ2 is never connected */
+               }
+
+               if (ELCR_fallback) {
+                       /*
+                        *  If the ELCR indicates a level-sensitive interrupt, we
+                        *  copy that information over to the MP table in the
+                        *  irqflag field (level sensitive, active high polarity).
+                        */
+                       if (ELCR_trigger(i))
+                               intsrc.mpc_irqflag = 13;
+                       else
+                               intsrc.mpc_irqflag = 0;
+               }
+
+               intsrc.mpc_srcbusirq = i;
+               intsrc.mpc_dstirq = i ? i : 2;          /* IRQ0 to INTIN2 */
+               MP_intsrc_info(&intsrc);
+       }
+
+       intsrc.mpc_irqtype = mp_ExtINT;
+       intsrc.mpc_srcbusirq = 0;
+       intsrc.mpc_dstirq = 0;                          /* 8259A to INTIN0 */
+       MP_intsrc_info(&intsrc);
 }
 
 static inline void __init construct_default_ISA_mptable(int mpc_default_type)
 {
-    struct mpc_config_processor processor;
-    struct mpc_config_bus bus;
-    struct mpc_config_ioapic ioapic;
-    struct mpc_config_lintsrc lintsrc;
-    int linttypes[2] = { mp_ExtINT, mp_NMI };
-    int i;
-
-    /*
-     * local APIC has default address
-     */
-    mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
-
-    /*
-     * 2 CPUs, numbered 0 & 1.
-     */
-    processor.mpc_type = MP_PROCESSOR;
-    /* Either an integrated APIC or a discrete 82489DX. */
-    processor.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
-    processor.mpc_cpuflag = CPU_ENABLED;
-    processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) |
-        (boot_cpu_data.x86_model << 4) |
-        boot_cpu_data.x86_mask;
-    processor.mpc_featureflag = boot_cpu_data.x86_capability[0];
-    processor.mpc_reserved[0] = 0;
-    processor.mpc_reserved[1] = 0;
-    for (i = 0; i < 2; i++) {
-        processor.mpc_apicid = i;
-        MP_processor_info(&processor);
-    }
-
-    bus.mpc_type = MP_BUS;
-    bus.mpc_busid = 0;
-    switch (mpc_default_type) {
-    default:
-        printk("???\nUnknown standard configuration %d\n",
-               mpc_default_type);
-        /* fall through */
-    case 1:
-    case 5:
-        memcpy(bus.mpc_bustype, "ISA   ", 6);
-        break;
-    case 2:
-    case 6:
-    case 3:
-        memcpy(bus.mpc_bustype, "EISA  ", 6);
-        break;
-    case 4:
-    case 7:
-        memcpy(bus.mpc_bustype, "MCA   ", 6);
-    }
-    MP_bus_info(&bus);
-    if (mpc_default_type > 4) {
-        bus.mpc_busid = 1;
-        memcpy(bus.mpc_bustype, "PCI   ", 6);
-        MP_bus_info(&bus);
-    }
-
-    ioapic.mpc_type = MP_IOAPIC;
-    ioapic.mpc_apicid = 2;
-    ioapic.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
-    ioapic.mpc_flags = MPC_APIC_USABLE;
-    ioapic.mpc_apicaddr = 0xFEC00000;
-    MP_ioapic_info(&ioapic);
-
-    /*
-     * We set up most of the low 16 IO-APIC pins according to MPS rules.
-     */
-    construct_default_ioirq_mptable(mpc_default_type);
-
-    lintsrc.mpc_type = MP_LINTSRC;
-    lintsrc.mpc_irqflag = 0;           /* conforming */
-    lintsrc.mpc_srcbusid = 0;
-    lintsrc.mpc_srcbusirq = 0;
-    lintsrc.mpc_destapic = MP_APIC_ALL;
-    for (i = 0; i < 2; i++) {
-        lintsrc.mpc_irqtype = linttypes[i];
-        lintsrc.mpc_destapiclint = i;
-        MP_lintsrc_info(&lintsrc);
-    }
+       struct mpc_config_processor processor;
+       struct mpc_config_bus bus;
+       struct mpc_config_ioapic ioapic;
+       struct mpc_config_lintsrc lintsrc;
+       int linttypes[2] = { mp_ExtINT, mp_NMI };
+       int i;
+
+       /*
+        * local APIC has default address
+        */
+       mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
+
+       /*
+        * 2 CPUs, numbered 0 & 1.
+        */
+       processor.mpc_type = MP_PROCESSOR;
+       /* Either an integrated APIC or a discrete 82489DX. */
+       processor.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
+       processor.mpc_cpuflag = CPU_ENABLED;
+       processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) |
+                                  (boot_cpu_data.x86_model << 4) |
+                                  boot_cpu_data.x86_mask;
+       processor.mpc_featureflag = boot_cpu_data.x86_capability[0];
+       processor.mpc_reserved[0] = 0;
+       processor.mpc_reserved[1] = 0;
+       for (i = 0; i < 2; i++) {
+               processor.mpc_apicid = i;
+               MP_processor_info(&processor);
+       }
+
+       bus.mpc_type = MP_BUS;
+       bus.mpc_busid = 0;
+       switch (mpc_default_type) {
+               default:
+                       printk("???\nUnknown standard configuration %d\n",
+                               mpc_default_type);
+                       /* fall through */
+               case 1:
+               case 5:
+                       memcpy(bus.mpc_bustype, "ISA   ", 6);
+                       break;
+               case 2:
+               case 6:
+               case 3:
+                       memcpy(bus.mpc_bustype, "EISA  ", 6);
+                       break;
+               case 4:
+               case 7:
+                       memcpy(bus.mpc_bustype, "MCA   ", 6);
+       }
+       MP_bus_info(&bus);
+       if (mpc_default_type > 4) {
+               bus.mpc_busid = 1;
+               memcpy(bus.mpc_bustype, "PCI   ", 6);
+               MP_bus_info(&bus);
+       }
+
+       ioapic.mpc_type = MP_IOAPIC;
+       ioapic.mpc_apicid = 2;
+       ioapic.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
+       ioapic.mpc_flags = MPC_APIC_USABLE;
+       ioapic.mpc_apicaddr = 0xFEC00000;
+       MP_ioapic_info(&ioapic);
+
+       /*
+        * We set up most of the low 16 IO-APIC pins according to MPS rules.
+        */
+       construct_default_ioirq_mptable(mpc_default_type);
+
+       lintsrc.mpc_type = MP_LINTSRC;
+       lintsrc.mpc_irqflag = 0;                /* conforming */
+       lintsrc.mpc_srcbusid = 0;
+       lintsrc.mpc_srcbusirq = 0;
+       lintsrc.mpc_destapic = MP_APIC_ALL;
+       for (i = 0; i < 2; i++) {
+               lintsrc.mpc_irqtype = linttypes[i];
+               lintsrc.mpc_destapiclint = i;
+               MP_lintsrc_info(&lintsrc);
+       }
 }
 
 static struct intel_mp_floating *mpf_found;
+extern void    config_acpi_tables(void);
 
 /*
  * Scan the memory blocks for an SMP configuration block.
  */
 void __init get_smp_config (void)
 {
-    struct intel_mp_floating *mpf = mpf_found;
+       struct intel_mp_floating *mpf = mpf_found;
+
+#ifdef CONFIG_X86_IO_APIC
+       /*
+        * Check if the ACPI tables are provided. Use them only to get
+        * the processor information, mainly because it provides
+        * the info on the logical processor(s), rather than the physical
+        * processor(s) that are provided by the MPS. We attempt to 
+        * check only if the user provided a commandline override
+        */
+       //XXX Xen config_acpi_tables();
+#endif
        
-    printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
-    if (mpf->mpf_feature2 & (1<<7)) {
-        printk("    IMCR and PIC compatibility mode.\n");
-        pic_mode = 1;
-    } else {
-        printk("    Virtual Wire compatibility mode.\n");
-        pic_mode = 0;
-    }
-
-    /*
-     * Now see if we need to read further.
-     */
-    if (mpf->mpf_feature1 != 0) {
-
-        printk("Default MP configuration #%d\n", mpf->mpf_feature1);
-        construct_default_ISA_mptable(mpf->mpf_feature1);
-
-    } else if (mpf->mpf_physptr) {
-
-        /*
-         * Read the physical hardware table.  Anything here will
-         * override the defaults.
-         */
-        if (!smp_read_mpc((void *)mpf->mpf_physptr)) {
-            smp_found_config = 0;
-            printk("BIOS bug, MP table errors detected!...\n");
-            printk("... disabling SMP support. (tell your hw vendor)\n");
-            return;
-        }
-        /*
-         * If there are no explicit MP IRQ entries, then we are
-         * broken.  We set up most of the low 16 IO-APIC pins to
-         * ISA defaults and hope it will work.
-         */
-        if (!mp_irq_entries) {
-            struct mpc_config_bus bus;
-
-            printk("BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n");
-
-            bus.mpc_type = MP_BUS;
-            bus.mpc_busid = 0;
-            memcpy(bus.mpc_bustype, "ISA   ", 6);
-            MP_bus_info(&bus);
-
-            construct_default_ioirq_mptable(0);
-        }
-
-    } else
-        BUG();
-
-    printk("Processors: %d\n", num_processors);
-    /*
-     * Only use the first configuration found.
-     */
+       printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
+       if (mpf->mpf_feature2 & (1<<7)) {
+               printk("    IMCR and PIC compatibility mode.\n");
+               pic_mode = 1;
+       } else {
+               printk("    Virtual Wire compatibility mode.\n");
+               pic_mode = 0;
+       }
+
+       /*
+        * Now see if we need to read further.
+        */
+       if (mpf->mpf_feature1 != 0) {
+
+               printk("Default MP configuration #%d\n", mpf->mpf_feature1);
+               construct_default_ISA_mptable(mpf->mpf_feature1);
+
+       } else if (mpf->mpf_physptr) {
+
+               /*
+                * Read the physical hardware table.  Anything here will
+                * override the defaults.
+                */
+               if (!smp_read_mpc((void *)mpf->mpf_physptr)) {
+                       smp_found_config = 0;
+                       printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
+                       printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
+                       return;
+               }
+               /*
+                * If there are no explicit MP IRQ entries, then we are
+                * broken.  We set up most of the low 16 IO-APIC pins to
+                * ISA defaults and hope it will work.
+                */
+               if (!mp_irq_entries) {
+                       struct mpc_config_bus bus;
+
+                       printk("BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n");
+
+                       bus.mpc_type = MP_BUS;
+                       bus.mpc_busid = 0;
+                       memcpy(bus.mpc_bustype, "ISA   ", 6);
+                       MP_bus_info(&bus);
+
+                       construct_default_ioirq_mptable(0);
+               }
+
+       } else
+               BUG();
+
+       printk("Processors: %d\n", num_processors);
+       /*
+        * Only use the first configuration found.
+        */
 }
 
 static int __init smp_scan_config (unsigned long base, unsigned long length)
 {
-    unsigned long *bp = phys_to_virt(base);
-    struct intel_mp_floating *mpf;
-
-    Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
-    if (sizeof(*mpf) != 16)
-        printk("Error: MPF size\n");
-
-    while (length > 0) {
-        mpf = (struct intel_mp_floating *)bp;
-        if ((*bp == SMP_MAGIC_IDENT) &&
-            (mpf->mpf_length == 1) &&
-            !mpf_checksum((unsigned char *)bp, 16) &&
-            ((mpf->mpf_specification == 1)
-             || (mpf->mpf_specification == 4)) ) {
-
-            smp_found_config = 1;
-            printk("found SMP MP-table at %08lx\n",
-                   virt_to_phys(mpf));
-            reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE);
-            if (mpf->mpf_physptr)
-                reserve_bootmem(mpf->mpf_physptr, PAGE_SIZE);
-            mpf_found = mpf;
-            return 1;
-        }
-        bp += 4;
-        length -= 16;
-    }
-    return 0;
+       unsigned long *bp = phys_to_virt(base);
+       struct intel_mp_floating *mpf;
+
+       Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
+       if (sizeof(*mpf) != 16)
+               printk("Error: MPF size\n");
+
+       while (length > 0) {
+               mpf = (struct intel_mp_floating *)bp;
+               if ((*bp == SMP_MAGIC_IDENT) &&
+                       (mpf->mpf_length == 1) &&
+                       !mpf_checksum((unsigned char *)bp, 16) &&
+                       ((mpf->mpf_specification == 1)
+                               || (mpf->mpf_specification == 4)) ) {
+
+                       smp_found_config = 1;
+                       printk("found SMP MP-table at %08lx\n",
+                                               virt_to_phys(mpf));
+                       reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE);
+                       if (mpf->mpf_physptr)
+                               reserve_bootmem(mpf->mpf_physptr, PAGE_SIZE);
+                       mpf_found = mpf;
+                       return 1;
+               }
+               bp += 4;
+               length -= 16;
+       }
+       return 0;
 }
 
 void __init find_intel_smp (void)
 {
-    /*
-     * 1) Scan the bottom 1K for a signature
-     * 2) Scan the top 1K of base RAM
-     * 3) Scan the 64K of bios
-     */
-    if (smp_scan_config(0x0,0x400) ||
-        smp_scan_config(639*0x400,0x400) ||
-        smp_scan_config(0xF0000,0x10000))
-        return;
+       unsigned int address;
+
+       /*
+        * FIXME: Linux assumes you have 640K of base ram..
+        * this continues the error...
+        *
+        * 1) Scan the bottom 1K for a signature
+        * 2) Scan the top 1K of base RAM
+        * 3) Scan the 64K of bios
+        */
+       if (smp_scan_config(0x0,0x400) ||
+               smp_scan_config(639*0x400,0x400) ||
+                       smp_scan_config(0xF0000,0x10000))
+               return;
+       /*
+        * If it is an SMP machine we should know now, unless the
+        * configuration is in an EISA/MCA bus machine with an
+        * extended bios data area.
+        *
+        * there is a real-mode segmented pointer pointing to the
+        * 4K EBDA area at 0x40E, calculate and scan it here.
+        *
+        * NOTE! There were Linux loaders that will corrupt the EBDA
+        * area, and as such this kind of SMP config may be less
+        * trustworthy, simply because the SMP table may have been
+        * stomped on during early boot.  Thankfully the bootloaders
+        * now honour the EBDA.
+        */
+
+       address = *(unsigned short *)phys_to_virt(0x40E);
+       address <<= 4;
+       smp_scan_config(address, 0x1000);
+}
+
+#else
+
+/*
+ * The Visual Workstation is Intel MP compliant in the hardware
+ * sense, but it doesn't have a BIOS(-configuration table).
+ * No problem for Linux.
+ */
+void __init find_visws_smp(void)
+{
+       smp_found_config = 1;
+
+       phys_cpu_present_map |= 2; /* or in id 1 */
+       apic_version[1] |= 0x10; /* integrated APIC */
+       apic_version[0] |= 0x10;
+
+       mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
 }
 
+#endif
+
 /*
  * - Intel MP Configuration Table
  * - or SGI Visual Workstation configuration
  */
 void __init find_smp_config (void)
 {
-    find_intel_smp();
+#ifdef CONFIG_X86_LOCAL_APIC
+       find_intel_smp();
+#endif
+#ifdef CONFIG_VISWS
+       find_visws_smp();
+#endif
 }
 
index 5b20a6c8c92e912c62ab73a35d34b1f99e32d01c..11fecb571bc14fd54a2d551d4f3529f9009ff343 100644 (file)
@@ -4,7 +4,8 @@ include $(BASEDIR)/Rules.mk
 default: $(OBJS)
        $(MAKE) -C ne
        $(MAKE) -C tulip
-       $(LD) -r -o driver.o $(OBJS) tulip/tulip.o ne/ne_drv.o
+       $(MAKE) -C e1000
+       $(LD) -r -o driver.o e1000/e1000.o $(OBJS) tulip/tulip.o ne/ne_drv.o
 
 clean:
        $(MAKE) -C ne clean
index ec7c27aa7e100d37364680afa68677dbeaa5004e..d94e390ba3ab2fb6acca0f1b8525f1d130a2042b 100644 (file)
 struct e1000_adapter;
 
 // XEN XXX
-#define DBG 1
+// #define DBG 1
 
 #include "e1000_hw.h"
 
 #if DBG
 #define E1000_DBG(args...) printk(KERN_DEBUG "e1000: " args)
 #else
-XXX
 #define E1000_DBG(args...)
 #endif
 
index 91053751c756550cebcb3a661f93016e2de8f4bb..1d70dab9371dc6d0a23d7c67a6332ca7d205f9fb 100644 (file)
@@ -1879,7 +1879,7 @@ e1000_read_phy_reg(struct e1000_hw *hw,
     uint32_t mdic = 0;
     const uint32_t phy_addr = 1;
 
-    DEBUGFUNC("e1000_read_phy_reg");
+    DEBUGFUNC("XXXXe1000_read_phy_reg");
 
     if(reg_addr > MAX_PHY_REG_ADDRESS) {
         DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
index 0d3b62505aa318825136932a22d70e9ddb8517ce..8afbe394c2f49e3cda0aaeda345b922ead1724e1 100644 (file)
@@ -301,11 +301,9 @@ e1000_reset(struct e1000_adapter *adapter)
 
        adapter->hw.fc = adapter->hw.original_fc;
        e1000_reset_hw(&adapter->hw);
-printk("RESET_H/W\n");
        if(adapter->hw.mac_type >= e1000_82544)
                E1000_WRITE_REG(&adapter->hw, WUC, 0);
        e1000_init_hw(&adapter->hw);
-printk("INIT H/W\n");
        e1000_reset_adaptive(&adapter->hw);
        e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
 }
@@ -470,14 +468,12 @@ e1000_probe(struct pci_dev *pdev,
 
        printk(KERN_INFO "%s: %s\n", netdev->name, adapter->id_string);
        e1000_check_options(adapter);
-printk("OPTIONS OVER\n");
        /* Initial Wake on LAN setting
         * If APM wake is enabled in the EEPROM,
         * enable the ACPI Magic Packet filter
         */
 
        e1000_read_eeprom(&adapter->hw, EEPROM_INIT_CONTROL2_REG, &eeprom_data);
-printk("EPROM OVER\n");
        if((adapter->hw.mac_type >= e1000_82544) &&
           (eeprom_data & E1000_EEPROM_APME))
                adapter->wol |= E1000_WUFC_MAG;
@@ -485,7 +481,6 @@ printk("EPROM OVER\n");
        /* reset the hardware with the new settings */
 
        e1000_reset(adapter);
-printk("PROBE OVER\n");
        cards_found++;
        return 0;
 
index e51e08347225bcf4aa9faa94b3bd495098e13f6e..fe3fff2af74173590cef90d8ccf1b2ca710fbeb0 100644 (file)
@@ -45,7 +45,7 @@
 #define msec_delay(x) {\
        int s=jiffies+1+((x*HZ)/1000); \
        printk("mdelay(%d) called -- spin\n",x); \
-       while(jiffies<s); printk("mdelay over\n");}
+       while(jiffies<s); }
 
 #if 0
 /********************  NOT in XEN ! *******/
@@ -73,7 +73,7 @@ typedef enum {
 #define ASSERT(x)      if(!(x)) BUG()
 #define MSGOUT(S, A, B)        printk(KERN_DEBUG S "\n", A, B)
 
-#define DBG 1
+//#define DBG 1
 
 #if DBG
 #define DEBUGOUT(S)            printk(KERN_DEBUG S "\n")
index 86dd0fbc66127538dd3b9c065b38d183d22471bc..166b68e0ffb8081232ce64b7635cb0276e2525f4 100644 (file)
@@ -1,9 +1,12 @@
 #ifndef __ASM_APIC_H
 #define __ASM_APIC_H
 
-#include <asm/system.h>
-#include <asm/ptrace.h>
+//#include <linux/config.h>
+//#include <linux/pm.h>
 #include <asm/apicdef.h>
+#include <asm/system.h>
+
+#ifdef CONFIG_X86_LOCAL_APIC
 
 #define APIC_DEBUG 0
 
@@ -37,9 +40,15 @@ static __inline__ void apic_wait_icr_idle(void)
        do { } while ( apic_read( APIC_ICR ) & APIC_ICR_BUSY );
 }
 
-#define FORCE_READ_AROUND_WRITE 0
-#define apic_read_around(x)
-#define apic_write_around(x,y) apic_write((x),(y))
+#ifdef CONFIG_X86_GOOD_APIC
+# define FORCE_READ_AROUND_WRITE 0
+# define apic_read_around(x)
+# define apic_write_around(x,y) apic_write((x),(y))
+#else
+# define FORCE_READ_AROUND_WRITE 1
+# define apic_read_around(x) apic_read(x)
+# define apic_write_around(x,y) apic_write_atomic((x),(y))
+#endif
 
 static inline void ack_APIC_irq(void)
 {
@@ -67,8 +76,24 @@ extern void setup_local_APIC (void);
 extern void init_apic_mappings (void);
 extern void smp_local_timer_interrupt (struct pt_regs * regs);
 extern void setup_APIC_clocks (void);
+extern void setup_apic_nmi_watchdog (void);
+extern inline void nmi_watchdog_tick (struct pt_regs * regs);
 extern int APIC_init_uniprocessor (void);
+extern void disable_APIC_timer(void);
+extern void enable_APIC_timer(void);
+
+//extern struct pm_dev *apic_pm_register(pm_dev_t, unsigned long, pm_callback);
+//extern void apic_pm_unregister(struct pm_dev*);
 
 extern unsigned int apic_timer_irqs [NR_CPUS];
+extern int check_nmi_watchdog (void);
+
+extern unsigned int nmi_watchdog;
+#define NMI_NONE       0
+#define NMI_IO_APIC    1
+#define NMI_LOCAL_APIC 2
+#define NMI_INVALID    3
+
+#endif /* CONFIG_X86_LOCAL_APIC */
 
 #endif /* __ASM_APIC_H */
index f855a7d88d828c160e981cc402be2be5f87208be..227bfca6528aacb632167142b021dba81867c03e 100644 (file)
@@ -32,6 +32,8 @@
 #define                        SET_APIC_LOGICAL_ID(x)  (((x)<<24))
 #define                        APIC_ALL_CPUS           0xFF
 #define                APIC_DFR        0xE0
+#define                        APIC_DFR_CLUSTER        0x0FFFFFFFul    /* Clustered */
+#define                        APIC_DFR_FLAT           0xFFFFFFFFul    /* Flat mode */
 #define                APIC_SPIV       0xF0
 #define                        APIC_SPIV_FOCUS_DISABLED        (1<<9)
 #define                        APIC_SPIV_APIC_ENABLED          (1<<8)
@@ -57,6 +59,7 @@
 #define                        APIC_INT_LEVELTRIG      0x08000
 #define                        APIC_INT_ASSERT         0x04000
 #define                        APIC_ICR_BUSY           0x01000
+#define                        APIC_DEST_PHYSICAL      0x00000
 #define                        APIC_DEST_LOGICAL       0x00800
 #define                        APIC_DM_FIXED           0x00000
 #define                        APIC_DM_LOWEST          0x00100
 
 #define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
 
+#ifdef CONFIG_X86_CLUSTERED_APIC
+#define MAX_IO_APICS 32
+#else
 #define MAX_IO_APICS 8
+#endif
+
+
+/*
+ * The broadcast ID is 0xF for old APICs and 0xFF for xAPICs.  SAPICs
+ * don't broadcast (yet?), but if they did, they might use 0xFFFF.
+ */
+#define APIC_BROADCAST_ID_XAPIC (0xFF)
+#define APIC_BROADCAST_ID_APIC  (0x0F)
 
 /*
  * the local APIC register structure, memory mapped. Not terribly well
index a03be4d733ecea272920c86821725fc9fcf08306..44916209a87c84c353d949faec64c6b3c26c2691 100644 (file)
@@ -15,7 +15,8 @@
 #define APIC_MISMATCH_DEBUG
 
 #define IO_APIC_BASE(idx) \
-               ((volatile int *)__fix_to_virt(FIX_IO_APIC_BASE_0 + idx))
+               ((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \
+               + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK)))
 
 /*
  * The structure of the IO-APIC:
@@ -96,7 +97,7 @@ extern struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
 extern int mp_irq_entries;
 
 /* MP IRQ source entries */
-extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
+extern struct mpc_config_intsrc *mp_irqs;
 
 /* non-0 if default (table-less) MP configuration */
 extern int mpc_default_type;
@@ -132,8 +133,7 @@ static inline void io_apic_sync(unsigned int apic)
 }
 
 /* 1 if "noapic" boot option passed */
-//extern int skip_ioapic_setup;
-#define skip_ioapic_setup 0
+extern int skip_ioapic_setup;
 
 /*
  * If we use the IO-APIC for IRQ routing, disable automatic
index 2598ea02db2f2b26e16bba1d290aaf0e8865f759..2829cb54a31eeb5a8987a9aa21f875869a691386 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __ASM_MPSPEC_H
 #define __ASM_MPSPEC_H
 
+
 /*
  * Structure definitions for SMP machines following the
  * Intel Multiprocessing Specification 1.1 and 1.4.
  
 #define SMP_MAGIC_IDENT        (('_'<<24)|('P'<<16)|('M'<<8)|'_')
 
-/* Maximum of 16 APICs with the current APIC ID architecture. */
+/*
+ * a maximum of 16 APICs with the current APIC ID architecture.
+ * xAPICs can have up to 256.  SAPICs have 16 ID bits.
+ */
+#ifdef CONFIG_X86_CLUSTERED_APIC
+#define MAX_APICS 256
+#else
 #define MAX_APICS 16
+#endif
 
 #define MAX_MPC_ENTRY 1024
 
@@ -178,7 +186,11 @@ struct mpc_config_translation
  *     7       2 CPU MCA+PCI
  */
 
+#ifdef CONFIG_MULTIQUAD
+#define MAX_IRQ_SOURCES 512
+#else /* !CONFIG_MULTIQUAD */
 #define MAX_IRQ_SOURCES 256
+#endif /* CONFIG_MULTIQUAD */
 
 #define MAX_MP_BUSSES 32
 enum mp_bustype {
@@ -187,8 +199,11 @@ enum mp_bustype {
        MP_BUS_PCI,
        MP_BUS_MCA
 };
-extern int mp_bus_id_to_type [MAX_MP_BUSSES];
-extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
+extern int *mp_bus_id_to_type;
+extern int *mp_bus_id_to_node;
+extern int *mp_bus_id_to_local;
+extern int *mp_bus_id_to_pci_bus;
+extern int quad_local_to_mp_bus_id [NR_CPUS/4][4];
 
 extern unsigned int boot_cpu_physical_apicid;
 extern unsigned long phys_cpu_present_map;
@@ -197,11 +212,9 @@ extern void find_smp_config (void);
 extern void get_smp_config (void);
 extern int nr_ioapics;
 extern int apic_version [MAX_APICS];
-extern int mp_bus_id_to_type [MAX_MP_BUSSES];
 extern int mp_irq_entries;
-extern struct mpc_config_intsrc mp_irqs [MAX_IRQ_SOURCES];
+extern struct mpc_config_intsrc *mp_irqs;
 extern int mpc_default_type;
-extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
 extern int mp_current_pci_id;
 extern unsigned long mp_lapic_addr;
 extern int pic_mode;
index 67bbedbd082b1159c36f67dd27000bea8f22d64c..ece215fab003a35139c38f8ca8501b4fef7a5a44 100644 (file)
@@ -1,13 +1,82 @@
 #ifndef __ASM_SMPBOOT_H
 #define __ASM_SMPBOOT_H
 
-#define TRAMPOLINE_LOW phys_to_virt(0x467)
-#define TRAMPOLINE_HIGH phys_to_virt(0x469)
+/*emum for clustered_apic_mode values*/
+enum{
+       CLUSTERED_APIC_NONE = 0,
+       CLUSTERED_APIC_XAPIC,
+       CLUSTERED_APIC_NUMAQ
+};
 
-#define boot_cpu_apicid boot_cpu_physical_apicid
+#ifdef CONFIG_X86_CLUSTERED_APIC
+extern unsigned int apic_broadcast_id;
+extern unsigned char clustered_apic_mode;
+extern unsigned char esr_disable;
+extern unsigned char int_delivery_mode;
+extern unsigned int int_dest_addr_mode;
+extern int cyclone_setup(char*);
 
-/* How to map from the cpu_present_map. */
-#define cpu_present_to_apicid(apicid) (apicid)
+static inline void detect_clustered_apic(char* oem, char* prod)
+{
+       /*
+        * Can't recognize Summit xAPICs at present, so use the OEM ID.
+        */
+       if (!strncmp(oem, "IBM ENSW", 8) && !strncmp(prod, "VIGIL SMP", 9)){
+               clustered_apic_mode = CLUSTERED_APIC_XAPIC;
+               apic_broadcast_id = APIC_BROADCAST_ID_XAPIC;
+               int_dest_addr_mode = APIC_DEST_PHYSICAL;
+               int_delivery_mode = dest_Fixed;
+               esr_disable = 1;
+               /*Start cyclone clock*/
+               cyclone_setup(0);
+       }
+       else if (!strncmp(oem, "IBM NUMA", 8)){
+               clustered_apic_mode = CLUSTERED_APIC_NUMAQ;
+               apic_broadcast_id = APIC_BROADCAST_ID_APIC;
+               int_dest_addr_mode = APIC_DEST_LOGICAL;
+               int_delivery_mode = dest_LowestPrio;
+               esr_disable = 1;
+       }
+}
+#define        INT_DEST_ADDR_MODE (int_dest_addr_mode)
+#define        INT_DELIVERY_MODE (int_delivery_mode)
+#else /* CONFIG_X86_CLUSTERED_APIC */
+#define apic_broadcast_id (APIC_BROADCAST_ID_APIC)
+#define clustered_apic_mode (CLUSTERED_APIC_NONE)
+#define esr_disable (0)
+#define detect_clustered_apic(x,y)
+#define INT_DEST_ADDR_MODE (APIC_DEST_LOGICAL) /* logical delivery */
+#define INT_DELIVERY_MODE (dest_LowestPrio)
+#endif /* CONFIG_X86_CLUSTERED_APIC */
+#define BAD_APICID 0xFFu
+
+#define TRAMPOLINE_LOW phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0x8:0x467)
+#define TRAMPOLINE_HIGH phys_to_virt((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?0xa:0x469)
+
+#define boot_cpu_apicid ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)?boot_cpu_logical_apicid:boot_cpu_physical_apicid)
+
+extern unsigned char raw_phys_apicid[NR_CPUS];
+
+/*
+ * How to map from the cpu_present_map
+ */
+static inline int cpu_present_to_apicid(int mps_cpu)
+{
+       if (clustered_apic_mode == CLUSTERED_APIC_XAPIC)
+               return raw_phys_apicid[mps_cpu];
+       if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
+               return (mps_cpu/4)*16 + (1<<(mps_cpu%4));
+       return mps_cpu;
+}
+
+static inline unsigned long apicid_to_phys_cpu_present(int apicid)
+{
+       if(clustered_apic_mode)
+               return 1UL << (((apicid >> 4) << 2) + (apicid & 0x3));
+       return 1UL << apicid;
+}
+
+#define physical_to_logical_apicid(phys_apic) ( (1ul << (phys_apic & 0x3)) | (phys_apic & 0xF0u) )
 
 /*
  * Mappings between logical cpu number and logical / physical apicid
@@ -22,7 +91,31 @@ extern volatile int cpu_2_physical_apicid[];
 #define cpu_to_logical_apicid(cpu) cpu_2_logical_apicid[cpu]
 #define physical_apicid_to_cpu(apicid) physical_apicid_2_cpu[apicid]
 #define cpu_to_physical_apicid(cpu) cpu_2_physical_apicid[cpu]
+#ifdef CONFIG_MULTIQUAD                        /* use logical IDs to bootstrap */
+#define boot_apicid_to_cpu(apicid) logical_apicid_2_cpu[apicid]
+#define cpu_to_boot_apicid(cpu) cpu_2_logical_apicid[cpu]
+#else /* !CONFIG_MULTIQUAD */          /* use physical IDs to bootstrap */
 #define boot_apicid_to_cpu(apicid) physical_apicid_2_cpu[apicid]
 #define cpu_to_boot_apicid(cpu) cpu_2_physical_apicid[cpu]
+#endif /* CONFIG_MULTIQUAD */
 
+#ifdef CONFIG_X86_CLUSTERED_APIC
+static inline int target_cpus(void)
+{
+       static int cpu;
+       switch(clustered_apic_mode){
+               case CLUSTERED_APIC_NUMAQ:
+                       /* Broadcast intrs to local quad only. */
+                       return APIC_BROADCAST_ID_APIC;
+               case CLUSTERED_APIC_XAPIC:
+                       /*round robin the interrupts*/
+                       cpu = (cpu+1)%smp_num_cpus;
+                       return cpu_to_physical_apicid(cpu);
+               default:
+       }
+       return cpu_online_map;
+}
+#else
+#define target_cpus() (0x01)
+#endif
 #endif